package gbench.sandbox.tree;

import static gbench.common.tree.LittleTree.IRecord.L;
import static gbench.common.tree.LittleTree.IRecord.REC;
import static gbench.common.tree.LittleTree.IRecord.REC3;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;

import gbench.common.tree.LittleTree.IRecord;
import gbench.common.tree.LittleTree.Node;

/**
 * 其实 IRecord 不光是一个  键值对儿的集合  而且 它还是 就是一个树形结构<br>
 * 把 IRecord 用作一个树形结构
 * @author gbench
 *
 */
public class JunitRecordTree {
    
    /**
     * 层级结构展示
     */
    @Test
    public void foo(){
        
        System.out.println("\n使用CallBack对象来进行处理");
        final var rec = REC3(REC("a/b/c", 123, "a/b/d", 456,"a/e",7), REC("f/g", 9, "h", 9,"i",L(1,2,3)));
        final var root = new Node<String>("root");// 生成根节点
        final var mm = new HashMap<List<String>,Node<String>>();// 树形结构的拼接缓存
        
        // 生成callback 对象
        class CallBack implements BiConsumer<String, Object> {
            /**
             * 构造函数
             * @param callback
             * @param parentPath
             */
            public CallBack(BiConsumer<List<String>, Object> callback,List<String>parentPath){
                this.callback = callback;
                this.parentPath = parentPath.stream().collect(Collectors.toList());
            }
            
            /**
             * 构造含糊
             * @param callback
             */
            public CallBack(BiConsumer<List<String>, Object> callback){
                this(callback,new LinkedList<String>());
            }
            
            @Override
            public void accept(final String key, final Object value) {
                final var node_path = Stream.concat(this.parentPath.stream(), Stream.of(key)).collect(Collectors.toList());// 拼接成新的路径
                final var node = mm.computeIfAbsent(node_path, k->new Node<String>(key));
                node.prop("value", value);
                final var parentNode = mm.compute(this.parentPath, (k,v)->v==null?root:v);
                if(parentNode!=node)parentNode.addChild(node);
                
                if (value instanceof IRecord) {
                    final var cb = new CallBack(callback,node_path);
                    ((IRecord)value).foreach(cb);
                } else {
                    this.callback.accept(node_path, value);
                }// if
            }
            
            private final BiConsumer<List<String>, Object> callback;// 回调函数
            private final List<String> parentPath;// 上级节点的path
        }
        
        // 结构遍历
        rec.foreach(new CallBack((path,value)->System.out.println(path+"-->"+value)));
        
        System.out.println("\n把一个IRecord转换成一个LittleTree的Node");
        // LittleTree 方式的节点遍历
        root.forEach(e->{
            System.out.println("\t".repeat(e.getLevel()-1)+""+e.getPath()+",value attribute is:"+e.prop("value"));
        });
        
    };

}
